package com.baitiaojun.security.core.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baitiaojun.common.utils.string.StringUtils;
import com.baitiaojun.security.core.domain.LoginUser;
import com.baitiaojun.security.core.domain.Role;
import com.baitiaojun.security.core.utils.SecurityUtils;
import com.baitiaojun.security.core.service.PermissionService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service("permit")
public class PermissionServiceImpl implements PermissionService {

    private static final String SEPERATOR = ",";

    /**
     * 判断是否符合指定的多个权限中的任意权限
     * @param permissions
     * @return
     */
    @Override
    public boolean hasAnyPermission(String permissions) {
        if (StringUtils.isEmpty(permissions)) {
            return false;
        }
        return Arrays.stream(permissions.split(SEPERATOR)).anyMatch(this::hasPermission);
    }

    /**
     * 判断是否具有某个指定权限
     * @param permission
     * @return
     */
    @Override
    public boolean hasPermission(String permission) {
        if (StringUtils.isEmpty(permission)) {
            return false;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            return false;
        }
        return hasPermission(permission, loginUser.getAuthorities());
    }

    /**
     * 判断是否符合指定多个角色中的任意角色
     * @param roles
     * @return
     */
    @Override
    public boolean hasAnyRole(String roles) {
        if (StringUtils.isEmpty(roles)) {
            return false;
        }
        String[] roleArr = roles.split(SEPERATOR);
        return Arrays.stream(roleArr).anyMatch(this::hasRole);
    }

    /**
     * 判断是否符合指定角色
     * @param role
     * @return
     */
    @Override
    public boolean hasRole(String role) {
        if (StringUtils.isEmpty(role)) {
            return false;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<Role> roles = loginUser.getUserInfo().getRoles();
        if (CollectionUtil.isEmpty(roles)) {
            return false;
        }
        return roles.stream().anyMatch(r->
                ADMIN.equals(r.getRoleName()) || role.equals(r.getRoleName()));
    }

    private boolean hasPermission(String permission, Collection<? extends GrantedAuthority> permissions) {
        if (CollectionUtil.isEmpty(permissions)) {
            return false;
        }
        Set<String> permissionSet = permissions.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
        return permissionSet.contains(ALL_PERMISSION) || permissionSet.contains(StringUtils.trim(permission));
    }
}
